Google Trends搜尋關鍵字熱度與 COVID-19疫情分析
一、摘要
在COVID-19病毒感染的肺炎疫情牽動社會人心的關鍵時刻,本研究將利用數據分析、視覺化的方法,圍繞疫情態勢展示進行分析,並挖掘數據與疫情之間的關聯,將圖像以R shiny 互動式網頁的方式生動地呈現給大家!
二、研究流程
三、研究方法
Google Trends搜尋關鍵字熱度與 COVID-19疫情趨勢的相關性
資料來源
關鍵字搜尋熱度數據取自Google Trends資料庫,設定分析條件為2022年1月1日至 2022年5月31日期間,在臺灣以特定關鍵字於Google搜尋引擎進行的網頁搜尋行為。 疫情資料取自衛生福利部疾病管制署TCDC發布之COVID-19每日確診數人數資料。
Google Trends系統將以區間內最高搜尋值作為比較基準,提供0至100的定量結果來顯示指定關鍵字的相對熱門程度,100表示該字詞在選定條件具有最高熱度,50則為最高熱度之一半,0則表示熱度資料不足。
依據本次研究目的, 我們將COVID-19相關的23個關鍵字分為疾病名稱、症狀、防護用品及行為、篩檢及健康管理和疫苗名稱共五類,分別於Google Trends 網站中依上述條件設定進行搜尋熱度分析。
統計方法
本次研究將使用R針對COVID-19確診個案數與Google Trends關鍵字搜尋熱度進行Pearson 相關係數(Pearson correlation coefficients)分析。
依照分析結果,Pearson相關係數
- >0.6定義為高度相關(good to excellent correlation);
- 0.4-0.6為中度相關(moderate correlation);
- <0.4則為低度相關(poor correlation)。
| 關鍵字分類 | COVID-19相關關鍵字 |
|---|---|
| 疾病名稱 | 肺炎、covid、omicron |
| 症狀 | 咳嗽、發燒、味覺、嗅覺、呼吸困難、後遺症 |
| 防護用品及行為 | 口罩、酒精、耳溫槍、血氧機 |
| 篩檢及健康管理 | 快篩、pcr、確診、陽性、居家隔離、檢疫 |
| 疫苗名稱 | AZ、BNT、Moderna、高端 |
視覺化疫情分析
使用ggplot2進行繪圖
- 台灣整體確診人數變化
- 各縣市每日確診人數變化
- 各縣市接種疫苗進度
四、重點程式碼
- 關鍵字熱度分析
整理並合併相同類別關鍵字資料
使用 inner_join() 以日期為key連接資料
最後整理出五筆資料
處理異常值
部分資料值呈現 <1 的文字形式,以0.5之數值取代
使用gsub()後再用as.numeric將文字轉換為數值
統計分析
cor.test()取得相關係數及p-value
mutate()分類相關係數的大小得出分析結果
cor <- c()
pvalue <- c()
for (i in (2:length(disease_data))){#對每個種類的關鍵字都進行一次
test <- cor.test(covid,disease_data[[i]],method = "pearson")
cor <- append(cor,test$estimate)
pvalue <- append(pvalue,test$p.value)
}
#合併所有結果並添加分析結果
result <- bind_rows(result1,result2,result3,result4,result5)
result <- result %>%
mutate("分析結果" = ifelse(cor>0.6,"高度相關",ifelse(cor>0.4,"中度相關","低度相關")))關鍵字熱度趨勢圖
pivot_longer()轉換成易繪圖之資料
geom_line()繪製折線圖
scale_x_date將x軸單位設成日期形式
- 視覺化疫情分析
互動式地圖
各縣市資料跟確診人數
選出符合我們所需要的範圍的資料
導入tidyr套件,使用spread()把data中需要的部分取出並且形成一個新data
#資料整理
newdata <- covid_data %>% filter(區域 == "全區"&縣市別 !=)
#newdata整理成左邊是縣市,方便跟地圖合併
team_name <- newdata[c("縣市別","個案公佈日","新增確診人數")]
newdata1 <- spread(team_name,key="個案公佈日",value="新增確診人數")
newdata1[is.na(newdata1)] <- 0讀取地圖資訊以及做資料整理,再把確診資料和地圖資料合併
導入sf套件,使用st_read()讀取地圖資料,使用sf的原因是可以保留檔案中繪圖的資訊,在之後畫地圖時也能更輕鬆地運用資料中geom的部分
地圖的R shiny呈現
ui介面做互動式選取時間選項,透過所選取的時間,回傳到server去判斷想要看到的確診資料
#ui部分
tabPanel("Map", titlePanel("各縣市每日新確診人數地圖"),
fluidRow(sidebarPanel(selectInput("time", "選取時間區間",choices=Date),),
tmapOutput("map", width = "100%", height = 800) )
)導入tmap使用qtm去畫出隨著日期變動的互動式地圖
全台新確診人數折線圖
R shiny server
ui介面提供拉桿選取時間區間
server透過回傳的時間,使用filter()去分析判斷所需要的資料
再使用ggplot()去畫出符合資料的折線圖
每日新增接種人次圖
資料整理
使用 group_by()將資料分組
across()將結尾為累計接種人次的資料用lag()計算出新增接種人次
minus = ~.x-dplyr::lag(.x)
data <- read_xlsx("vaccine_data.xlsx")
data <- data %>% rename(brand = "疫苗廠牌",date = "統計日期")
data$date = as.Date(data$date)
data$brand[data$brand=="Oxford/AstraZeneca"]="AZ"
data <-data %>% filter(brand != "ALL") %>% group_by(brand)%>%
mutate(across(ends_with("累計接種人次")
,minus
,.names = "new_{.col}")
)
data[data<0] <-0繪圖
使用geom_bar()繪製長方圖
透過theme()微調來美化繪圖成果
scale_y_continuous(labels = scales::comma)將座標軸尺度加上comma
data %>%
ggplot(aes(fill=brand,x=date,y = data$new_追加劑累計接種人次))+
geom_bar(position="stack", stat = "identity")+
labs(y = "numbers")+
theme_bw()+
theme(axis.text = element_text(size = 15),
axis.title = element_text(size = 18),
legend.title = element_text(size = 15),
legend.text = element_text(size = 13))+
scale_y_continuous(labels = scales::comma)全台疫苗覆蓋率圖表
使用geom_point geom_line 同時畫出折線及散佈點圖
scale_y_continuous(labels = scales::percent)將座標軸尺度以百分比呈現
五、結果呈現
- googletrend關鍵字熱度與疫情趨勢相關性
關鍵字熱度與確診人數趨勢對照圖
透過觀察圖表,可看出篩檢與健康管理類別與疫情趨勢一致,而其他種類的關鍵字則在年初即有不低的討論度,透過之後的統計分析我們可以進一步驗證關鍵字與疫情關聯性的大小。
統計分析結果
| 關鍵字 | cor | pvalue | 分類 | 分析結果 |
|---|---|---|---|---|
| 陽性 | 0.9323291 | 0.0000000 | 篩檢及健康管理 | 高度相關 |
| pcr | 0.9190472 | 0.0000000 | 篩檢及健康管理 | 高度相關 |
| 咳嗽 | 0.9027947 | 0.0000000 | 症狀 | 高度相關 |
| 發燒 | 0.8823547 | 0.0000000 | 症狀 | 高度相關 |
| 耳溫槍 | 0.8234622 | 0.0000000 | 防護用品及行為 | 高度相關 |
| 酒精 | 0.8172245 | 0.0000000 | 防護用品及行為 | 高度相關 |
| 快篩 | 0.7882602 | 0.0000000 | 篩檢及健康管理 | 高度相關 |
| 居家隔離 | 0.7870859 | 0.0000000 | 篩檢及健康管理 | 高度相關 |
| 肺炎 | 0.7468937 | 0.0000000 | 疾病名稱 | 高度相關 |
| 血氧機 | 0.7283516 | 0.0000000 | 防護用品及行為 | 高度相關 |
| 後遺症 | 0.7252594 | 0.0000000 | 症狀 | 高度相關 |
| 檢疫 | 0.7131920 | 0.0000000 | 篩檢及健康管理 | 高度相關 |
| covid | 0.6736642 | 0.0000000 | 疾病名稱 | 高度相關 |
| 味覺 | 0.6707678 | 0.0000000 | 症狀 | 高度相關 |
| 確診 | 0.6459164 | 0.0000000 | 篩檢及健康管理 | 高度相關 |
| 嗅覺 | 0.5054915 | 0.0000000 | 症狀 | 中度相關 |
| 呼吸困難 | 0.4930828 | 0.0000000 | 症狀 | 中度相關 |
| omicron | 0.3730834 | 0.0000056 | 疾病名稱 | 低度相關 |
| 口罩 | 0.2225345 | 0.0082253 | 防護用品及行為 | 低度相關 |
| bnt | 0.1328475 | 0.1176477 | 疫苗名稱 | 低度相關 |
| 高端 | -0.0098712 | 0.9078480 | 疫苗名稱 | 低度相關 |
| moderna | -0.0784825 | 0.3566777 | 疫苗名稱 | 低度相關 |
| az | -0.2539096 | 0.0024688 | 疫苗名稱 | 低度相關 |
經由研究結果得知,特定關鍵字詞的網路搜尋熱度與COVID-19當日的確診人數具有顯著相關性,例如covid、後遺症、快篩、確診、陽性等關鍵字;另AZ、Moderna、BNT、口罩等關鍵字則顯示低度相關。
上述結果說明了網路搜尋熱度與疫情趨勢具有程度不等的一致性,而其中以篩檢與健康管理類別的關鍵字呈現最高的關聯性,可知
在2022的疫情中,因為大量的爆發案例,人們更在乎如何去做篩檢、辨別自己是否確診,而相對的,疫苗與口罩因為已有一定程度的覆蓋率及足夠的存貨,人們對此的關注度也與疫情的關聯下降。
- 2022疫情分析_互動式頁面
請點擊:進入 R shiny網頁
此部分的結果呈現,我們以R shiny套件做出互動式網頁,讓疫情情況探索更為直覺及方便!
新確診案例
各縣市Covid19每日新確診案例地圖呈現
R Shiny互動式地圖
可以改變背景圖層、看到街道的背景,也可以把背景改為灰色,只要透過左邊按鈕就可以轉換
按一下縣市就會出現縣市名稱、日期以及新增確診人數
根據日期變更資料
選擇日期,資料會隨著日期更動並且畫出不同地圖
全台每日新增確診案例折線圖
互動式拉桿選擇想要觀察的日期區間,會依照時間區間給出相應的折線圖
由這樣的折線圖可以知道全台新增確診人數的趨勢和變動
疫苗施打情況
每日新增接種人次
可自由選取時間區間及顯示的疫苗廠牌,了解不同時間段的疫苗廠牌接種情形
疫苗覆蓋率
可自由選取時間區間查看各劑次覆蓋率的變化,了解各時間段的疫苗覆蓋率
六、問題回答
1. 想法來源
在2022台灣疫情確診人數在3月底到4月初又開始急速增長,也引起了我們的關注,所以我們起初想要針對確診人數的資料作分析判斷。
但在找尋資料的過程中,因為需要輸入大量的關鍵詞去找到相關資訊,所以我們發覺疫情的趨勢變動也會影響到人們搜索詞彙去了解、關注疫情狀況的行為,因此我們決定將搜尋熱度和確診人數做分析,了解人們對於疫情再次擴散以及染疫情形嚴重是否關心。
同時也探討目前在台灣各縣市人口的染疫情況,藉由互動式視覺化圖片去了解現在疫情人口的分佈以及嚴重程度。
2. R指令與技巧
- 資料處理
透過tidyverse系統內套件,將資料整理成易懂且方便繪圖的形式,或是透過group_by、filter等指令對資料做分析 - 圖表美化
利用theme(),改變圖表內的顏色、字體大小等⋯⋯,使得圖表更易閱讀 - R markdown呈現
使用knitr、kableExtra,美化我們的rmd,再透過<font color=></font>的指令,改變字體顏色
使用CSS語法固定程式碼呈現的高度 - 互動式網頁架設
利用shiny套件,透過dateRangeInput()等指令,將ggplot2所畫圖表變成可互動式
3. 使用的Packages
總共使用了10組套件
上課所教套件
- dplyr :
across()、arrange()、desc()、rename()、filter()、group_by()、lag()、mutate()、bind_rows、between() - ggplot2 :
ggplot()、geom_bar()、geom_line()、geom_point() - tidyr :
pivot_longer()、spread() - readr :
read_csv() - readxl :
read_xlsx()
新套件
- shiny :
tabPanel()、sidebarLayout()、checkboxGroupInput()、dateRangeInput() - sf :
st_read() - tmap :
qtm() - DT :
datatable() - kableExtra :
scroll_box()
(四)最困難的部分
遇到最困難的部分是在將網站上線到shiny的網頁,在R studio跑我們的專案時都一切正常,但在上傳時卻會出現error,一開始在網路上尋找了非常多的辦法都無法解決,最後才終於在stackoverflow這個網站上找到辦法,原來這個error是因為shiny server的locale與我們的專案不相同,透過改變Rprofile.site中的設定才終於上傳成功!